perm filename WISE.RES[UP,DOC] blob sn#272450 filedate 1977-03-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	A FEW WORDS OF WISDOM
C00008 00003	THE MACRO FACILITY (General Discussion)
C00015 00004	ADDITIONAL COMMANDS TO DESK CALCULATOR
C00018 00005	THE EDITOR
C00024 00006	THE MACRO LANGUAGE
C00039 00007	LANGUAGE SUMMARY
C00041 ENDMK
C⊗;
A FEW WORDS OF WISDOM

	WISE is a rather fancy desk calculator which was written
originally by Bill Weiher and modified considerably by Dick Sweet.
It is a stack machine with 10 addressable registers and a stack
capable of containing 100 (decimal) entries.  Visible on the screen
are the named registers and the top 6 elements of the stack.

	The program runs on either a Data Disc, III, or Datamedia
display.  You may move from one to the other if you type REE instead
of CON when you reattach.  The REE command simply looks at the display
type, adjusts some tables if necessary, and then continues where you
left off.  (Probably not true of Datamedias.)

	The real power of the calculator comes from the macro facility.
WISE allows one to define up to 26 macros.  These can take arguments
from the stack and can return multiple values on the stack.  They can
also use the named registers or even request numbers to be typed in
by the user.  Programs can be modified by an editor similar to SOS,
and can be saved and restored on the disk.

THE DESK CALCULATOR

	WISE allows the user to do calculations with more accuracy
than SAIL and with less trouble than the LISP "bignum" package.
Arithmetic is done using scaled fixed point double word integers
and has an accuracy of 20 decimal digits and an exponent range
(i.e. power of ten) of between -99 and 99.

	The screen shows the 10 registers, named A through J, and
the top 6 elements of the stack.  It actually shows the bottom
6 elements since the stack is a "push-up stack", but for this
description, we will speak of the "top" of the stack, even though
it is displayed on the bottom.

	As a new number is entered, it becomes the new top of
the stack.  You can correct mistakes with the backspace key until
the number is the "official" top of stack.  This happens when
a non-number-forming character such as an operator or a blank
is struck.  At this time, the number is normalized and placed
onto the stack.  To indicate a power of ten, enter the letter
"E", followed by the power of ten.  Since "-" is a binary operator,
the character "<" is used to denote a unary minus when entering
a negative number.  However, "-" is used for the power of ten
since the meaning is clear from context.

	Numbers can be recalled to the top of the stack from the
named registers by simply typing the name of the register.  This
is true not only for registers A-J, but also for the remainder 
register R which is set by the integer divide operation.  The
character "π" denotes pi to 20 significant digits.

OPERATORS:
	These operators use the top two elements of the stack
and replace the operands by the result.

+			ADD top two elements
-			SUBTRACT top from second
*			MULTIPLY top two elements
/			DIVIDE top into second
\			DIVIDE second into top
%			INTEGER DIVIDE top into second, remainder to R
&			INTEGER DIVIDE second into top, remainder to R
↑			EXPONENTIATE, raise second to top power

FUNCTIONS:
	The functions all operate on the top of the stack except ARCTAN2
		which operates on the top two elements.

~			ROUND OFF to 15 significant digits
$			CHANGE SIGN
|			ABSOLUTE VALUE
<meta>R			SQUARE ROOT
<meta>S			SINE
<meta>C			COSINE
<meta>L			LOG (to the base e)
<meta>E			EXPONENTIAL
<meta>A			ARCTANGENT
<meta>T			ARCTAN2 (Arctangent of top divided by second)

MISCELLANEOUS OPERATIONS:

=			DUPLICATE top of stack
X			EXCHANGE top two elements
→<register name> 	STORE top of stack in register 
  or ←<reg name>		(does not disturb stack)
>			POP top of stack, never to be seen again
Z			ZERO STACK
<form feed>		REWRITE SCREEN

THE MACRO FACILITY (General Discussion)

	In order to extend the power of the desk calculator, one can
define macro operations.  There can be up to 26 macros defined at any
given time.  Each macro has a single character name.  One calls a macro
by typing the macro name with the <control> key held down.  That is, to
call macro A, you type <control>A.  Macros may take arguments from
the stack, or they may just operate on the named registers.  Results
can be returned on the stack, either single or multiple results.

	There are various operations available to compiled macros
which cannot be accessed by a person simply using the desk calculator.
These include the ability to branch, either conditionally or 
unconditionally, several operations designed to simplify FOR statement
execution, and the ability to temporarily push items onto the system
pushdown stack, which allows the calculator stack to be rearranged
to some extent without effecting the named registers.

	Programs variables are limited to the 10 named variables
A-J.  However, there are provisions for saving these registers when
a macro (program) is entered.  When program arguments are initially
stored in registers, the previous values of the registers are
automatically saved and then restored upon exit from the program.
Any other registers may be saved on entry and restored on exit
by using the NEW construction (see below).

	Programs may use the stack as well as the named variables
for its operations.  If a program statement is simply an expression,
its value is pushed on the stack.  If a function, such as
SIN, is not followed by an argument in the source program, the compiled
program will use the top of the stack as the argument to the function.
There is even a "null" function "TOP" which simply returns the
top of the stack as its value.  The multiple store operation is
used to store several stack elements into several registers.

	However, a certain amount of care must be taken if the top of
the stack is used in expressions.  The compiler parses the expressions
in a left to right fashion and places intermediate results on the
stack.  Thus, if a function is used without arguments in some place other
than the first variable of an expression, the "top" of the stack will
probably be something other than what you plan it to be!  For example:

	4;A←2+SIN;

will compile as code to set A=4+sin(2).

	Another limitation in using the stack is motivated by the
fact that programs use the stack for saving registers upon entry.
Any information that is on the stack at the end of a program must
be removed in order to get to the saved register values.  This is
accomplished by remembering the status of the stack on entry and
"synchronizing" the stack on exit.  Programs can return one or
more values on the stack by using the RETURN statement.  In this
case, the RETURNed values are pushed onto the system stack, the
saved register values are restored, and the RETURNed values are
popped back onto the calculator stack.  However, it should be 
noted that the stack synchronization takes place BEFORE the
expressions are evaluated for the RETURN statement.  If one does
has no RETURNed values, formal paramaters, or NEW variables, and 
wishes to inhibit this stack synchronization, he can precede his 
macro definition with the reserved word NOSYNC.

	The compiler generates "code" in the form of a string of 9
bit characters, corresponding to the keyboard with <control> and
<meta> bits.  During program execution, the calculator reads from
this string rather than from the keyboard.  Several of the operation
routines, such as GO TO check to see that a macro is being executed
and are NO-OP's otherwise.  It is possible to get the calculator to
stop reading from the string and go back to the keyboard in the
following manner:
	Type <call> (↑C)
	Type REE
The reentry routine simply zeroes the macro string pointer and
continues WISE where it was interrupted.  There may be all
sorts of junk on the stack, such as saved register values, but
at least the keyboard will be back in control!


ADDITIONAL COMMANDS TO DESK CALCULATOR

	The following commands are related to the macro
facility of WISE.  They are recognized at the level of the
of the main control loop of WISE (i.e., they are not editor
commands).

Let αε{A,B,...,Z},

Mα	Macro edit α.  Call the editor, in insert mode if no
	macro α already exists.

Sα	Save macro text for α in a file names WISEα.MCR.

Lα	Load the macro text for α from the file WISEα.MCR.  If
	there is already text for α, replace it.

Kα	Compile α.  This is not necessary, since macros are
	automatically compiled the first time they are used.
	However, it is useful for checking macro syntax.

T	Text function.  Enter the editor to create a temporary
	macro that is compiled, executed, and forgotten immediately
	upon exit from the editor.

Pα	Print the generated code for α.  This is of use mainly
	for compiler debugging.

Q	Reverse the value of the macro print toggle.  Usually the
	screen is locked during macro execution in order to speed
	things up.  Typing Q an odd number of times will allow one
	to see the macro execution in all its gory detail.  In any
	case, the screen is unlocked at each PAUSE statement and
	whenever an input is prompted by the IN function.

REE	A system level command, given after typing <call>(↑C) that
	terminates macro interpretation.  It is also used when moving
	a program from a III display to a Data Disk, or DD to III.


THE EDITOR

	WISE contains a rather simple minded editor to allow
users to enter and correct macros.  It is a line oriented editor
which resembles SOS, with several distinctions.  The lines
have "floating" numbers.  The first line is line 1, the next one 2,
and so forth.  When new lines are inserted in the middle, the numbers
of the lines at the end increase.  The following description should
be sufficient for using the editor.

SYNTAX:

<line number> ::= <integer> | . | *

<range> ::=	<line number> | <line number>:<line number> |
		 <line number>!<integer>

<command> ::=	<insert> | <delete> | <print> | <alter> | <join> | <find> |
		 <exit> | <quit> | <nextline> | <prevline> | <prntdot> |
		 <rename>

<insert> ::=	I<line number>

<delete> ::=	D<range>

<print> ::=	P | P<range>

<alter> ::=	Z<line number>

<join> ::=	J<line number>

<find> ::=	F<string><alt mode><range> | F<string><alt mode> | F

<exit> ::=	E

<quit> ::=	Q

<nextline> ::=	<line feed>

<prevline> ::=	<alt mode>

<prntdot> ::=	=

<rename> ::=	R<letter>

SEMANTICS:

1. "." refers to the current line, "*" refers to the last line.

2. α:β means all lines whose numbers are between α and β inclusive.

3. α!n means n lines, starting at α

4. Lines are inserted after the named line.  If it is desired to
   insert lines at the beginning of the text, the command I0 will
   do this.

5. When the editor is in insert mode, it prompts with a "*".
   Otherwise, it prompts with a "→".

6. Insertion is terminated by an alt mode.  However, unlike SOS,
   if the alt mode is typed at the end of a non-blank line, the
   line is retained in the text.

7. Insertion does not change ".".  Thus, after inserting any number
   of lines, "." still points to the line after which the new
   lines were inserted.

8. If the print command is given without a range, it is as if the
   range ".:*" was specified.

9. The alter command gives the line to the system line editor in
   a manner similar to the Z command of SOS.

10. The join command removes the carriage return and line feed
   between the named line and the next line.  It also decreases
   the line number of all subsequent lines.

11. The find command moves the line pointer "." to the next line
   which contains the string.  If no such line exists, the value
   of "." is unchanged.  If there is no range given, the value
   ".:*" is used.  If the string is null, the last search string is
   used.  The command consisting of simply "F" searches for the
   previous string in the range ".+1:*".

12. When the compiler detects an error, it calls the editor with
   a pointer to the location of the error.  Normally, control returns
   to the main calculator loop upon exit from the editor.  However,
   with a text function (command T above), the source would be lost,
   so the compiler is recalled on exit.  The quit command will exit
   to the main calculator loop in any case.

13. When the command "=" is typed, the numerical value of "." is printed.

14. The rename command is used to change the name of a macro.  If 
   a "text function" (see calculator T command) is renamed, the macro
   is not executed upon exit from the editor.


THE MACRO LANGUAGE

	Macros for the WISE calculator are written in an ALGOL-like
language.  There are several differences, however, reflecting the
stack nature of WISE.  In the following description, undefined non-
terminals are the obvious thing.
 
SYNTAX

<program> ::= <block> | ( <arglist> ) <block> | NOSYNC <stmt>

<block> ::= <stmt> | NEW <arglist> ; <stmt>

<arglist> ::= <vrbl> | <vrbl> , <arglist>

<vrbl> ::= A | B | C | D | E | F | G | H | I | J

<stmt> ::= <polstmt> | <gostmt> | <retstmt> | <astmt> | <pause stmt> |
	   <condstmt> | <forstmt> | <whlstmt> | <cmnt> | <empty> |
	   <compd stmt> | <expr> | <label> : <stmt>

<polstmt> ::= POL <character string not containing ;>

<gostmt> ::= GO <label> | GO TO <label>

<label> ::= <a string of letters and digits, starting with a letter, of
	     length≤64, but not a vrbl or reserved word>

<retstmt> ::= RETURN | RETURN ( <exprlist> )

<exprlist> ::= <expr> | <expr> , <exprlist>

<astmt> ::= <mulstor> ← <expr>

<mulstor> ::= <vrbl> | { <arglist> }

<pause stmt> ::= PAUSE <character string not containing ;>

<condstmt> ::= IF <expr> THEN <stmt> | IF <expr> THEN <stmt> ELSE <stmt>

<forstmt> ::= FOR <vrbl> ← <forlist> DO <stmt>

<forlist> ::= <forlstel> | <forlstel> , <forlist>

<forlstel> ::= <expr> | <expr> STEP <expr> UNTIL <expr> |
	       <expr> STEP <expr> WHILE <expr> | <expr> WHILE <expr>

<whlstmt> ::= WHILE <expr> DO <stmt>

<cmnt> ::= COMMENT <character string not containing ;>

<compd stmt> ::= BEGIN <compd tail>

<compd tail> ::= <stmt> END | <stmt> ; <compd tail>

<expr> ::= <sexp> | IF <expr> THEN <expr> ELSE <expr>

<sexp> ::= <bfac> | <sexp> ∨ <bfac>

<bfac> ::= <bsec> | <bfac> ∧ <bsec>

<bsec> ::= <relat> | ¬ <relat>

<relat> ::= <aexp> | <aexp> <relation> <aexp>

<relation> ::= < | ≤ | = | ≠ | ≥ | >

<aexp> ::= <term> | + <term> | - <term> | <aexp> + <term> | <aexp> - <term>

<term> ::= <factor> | <term> <mulop> <factor>

<mulop> ::= * | / | % | DIV | REM | MOD

<factor> ::= <primary> | <factor> ↑ <primary>

<primary> ::= TRUE | FALSE | <number> | <funcall> | PI | π | ( <expr> ) |
	      <macrocall> | <assign> | <vrbl> | <prompt>

<funcall> ::= <function name> | <function name> ( <exprlist> )

<function name> ::= SIN | COS| LOG | EXP | ABS | TOP | SQRT |
		    ARCTAN | ARCTAN2 | IN

<assign> ::= <vrbl> ← <expr>

<macrocall> ::= <letter> ( <exprlist> ) | <letter> ( )

<prompt> ::= PROMPT ( <string not containing )> )

SEMANTICS

1. A macro definition begins with an optional list of arguments.
   When a program is entered, the current value of the variables
   in the arglist are saved and the top n elements of the stack are
   popped into the corresponding variables.  The order in which the
   variables are filled is from right to left.  Thus if the macro
   begins (A,C,G,B)... , register B will get the "top" of the stack,
   G the next, etc.  This makes more sense when you consider the 
   "push up" configuration of the stack on the screen.  If you are
   wondering how the old values can be saved on the stack and the
   new ones obtained from it, remember that the compiled programs 
   have another stack available to hold the saved values until after 
   the arguments have been taken from the stack.  At this time, the
   saved values are placed on the calculator stack.  The reserved
   word NOSYNC inhibits saving on the stack and also inhibits
   stack synchronization upon exit (see Note 5).

2. The NEW construction is implemented simply.  It causes the
   variables to be stacked, and then remembers to unstack them
   whenever the program is exited.

3. The POL statement allows the programmer to enter any series
   of characters which is passed essentially unchanged to the
   compiled code.  Thus any Polish string of operations can be
   specified.  Compiled code is a string of 9 bit characters,
   reflecting the <control> and <meta> bits available on the
   keyboard.  To specify <control>, precede a character by α.
   Precede a character by β to specify <meta>.  POL statements
   must be terminated by a ";".

4. The label of a GO TO statement cannot be a variable name or
   a reserved word.  Reserved words are all those words capitalized
   in the above grammar plus a few others.  Take your chances.

5. The RETURN statement specifies an exit from a macro.  It
   causes several things to happen, in the following order:
     a. The stack is restored to its state immediately after
	entry to the program (i.e., after variables were saved).
     b. The expressions of the <exprlist> are evaluated and saved
	on the system stack.
     c. The saved register values are restored from the stack.
     d. The "returned" values are recalled to the stack.
     e. Control is returned to the calling program, or the main
	calculator loop, if this is the top level program.
   There are several important things to be noted.  First, step (a)
   above is accomplished simply by removing 0 or more stack entries
   until the stack size corresponds to what it was on entry.  The
   calculator gets confused and angry when there are already too
   few stack elements.  For this reason, not even programs that
   have no arguments or NEW variables can use up more stack entries
   than they create.  Macros that begin with the reserved word NOSYNC
   do things differently.  Since the system has saved nothing on the
   stack, steps (a) & (c) are not done.  Return expressions are illegal with
   NOSYNC, so steps (b) & (d) are not done.  In this case, the program
   simply returns.  

6. The multiple store option causes the top several elements of the
   stack to be stored in registers.  For example, 
      {D,G,A}← <expr>
   will compile as code to evaluate <expr>, store the top of the
   stack in A, the next element in G, and the third element in D.
   As the values are stored, they are removed from the stack, so
   in the above example, three elements would be removed from the
   stack.

7. The PAUSE statement causes a message to be displayed at the
   bottom of the screen and program execution to be interrupted.
   Execution continues when a single character, the value of which
   is ignored, is typed.  Another feature of the PAUSE statement
   is that it allows the user to see the state of the stack and
   variables at a point during program execution.  Usually, the
   screen doesn't change until after the macro has exited, but
   the displaying of the message causes new values of registers
   and stack entries to be displayed as well.  See the Q command
   to the calculator (above) for further discussion.

8. Any expression can be used as a boolean value in a conditional
   expression.  If the expression is equal to zero, the TRUE
   branch is taken.  A non-zero value designates false.  This
   is the opposite of the scheme used by some other languages,
   such as SAIL.  If a truth valued expression, such as a relation,
   is used in an arithmetic context, it has a value of 0 if TRUE
   and 1 if FALSE.

9. In a FOR statement, the STEP expression (if present) is evaluated
   twice for each time through the loop if there is an UNTIL clause.
   First it is evaluated as the increment, then to be used
   in determining the proper test for completion.  For example,

     FOR r←α STEP ε UNTIL β DO s;

   is roughly equivalent to the following program:

	r←α;
	GO TO L2;
  L1:	r←r+ε;
  L2:	IF (r-β)*ε>0 THEN GO TO L3;
	s;
	GO TO L1;
  L3:

10. There is a bit of redundancy in the <mulop>'s.  "%" and DIV
   are equivalent, and denote integer division.  This means, the
   number of times that the second operand will go evenly into the
   first.  REM and MOD are equivalent and denote the remainder 
   after the integer divide operation. For example,
	π REM 2 = 1.1415926535897932384 .

11. The expression syntax is sufficiently similar to all other
   algorithmic languages that one should have no trouble figuring
   out expressions.  The functions are the only thing that might
   need some more explanation.  It has already been mentioned above
   that any arguments not supplied to functions in explicit
   arguments lists are taken from the top of the stack.  The 
   function TOP is merely a syntactic convenience to allow the
   top of the stack to be used in expressions.  As a one argument
   function that returns that argument, it compiles as no code at
   all.  If you wish to duplicate the top of the stack, the fastest
   way to do that is "POL =;".  The IN function causes a number
   to be prompted for input.  It also unlocks the display as
   described for the PAUSE statement.

12. The assignment statement statement causes the top of the stack
   to be popped off after it is stored, but an assignment used in
   an expression context is retained until the value is used.  Thus
   to make an assignment and also leave something on the stack,
   simply enclose the outer assignment in parentheses.  This obviously
   won't work for multiple stores.

13. The PROMPT function is similar to the IN function with the difference
   being that the user supplies the desired prompt.  All characters
   between the parentheses (up to 39 of them) are displayed at the
   bottom of the screen and the number typed in is returned as the value.


LANGUAGE SUMMARY

	The following is an informal summary of the macro language 
facility in WISE.  Let the following abbreviations apply in the summary:

	s - a statement
	e - an expression
	r - a storable register (A-J)
	d - a digit

PROGRAM:

	s
	(r,...,r) s
	NEW r,...,r; s
	(r,...,r) NEW r,...,r; s
	NOSYNC s

STATEMENT:

	POL ... ;
	GO label
	GO TO label
	RETURN
	RETURN (e,...,e)
	r←e
	{r,...,r}←e
	PAUSE ... ;
	IF e THEN s
	IF e THEN s ELSE s
	FOR r←e STEP e UNTIL e DO s
	FOR r←e STEP e WHILE e DO s
	FOR r←e WHILE e DO s
	FOR r←e,...,e DO s
	FOR r←<any combination of the above> DO s
	WHILE e DO s
	COMMENT ... ;
	BEGIN s;...s END
	e
	label: s
	<empty>

CONSTANTS:

	dddddddd
	ddddddd.dddd
	ddddEdd
	dddd.ddEdd
	dddE-dd
	ddd.ddE-dd
	TRUE
	FALSE
	PI
	π

FUNCTIONS:

	SIN
	COS
	LOG
	EXP
	ABS
	TOP
	SQRT
	ARCTAN
	ARCTAN2
	IN
	PROMPT(...)

OPERATORS: (in order of increasing precedence)

	∨
	∧
	¬
	< ≤ = ≠ ≥ >
	+ -
	* / % DIV REM MOD
	↑